import datetime

from django.contrib.auth import get_user_model
from django.db import models
from django.contrib.auth.models import AbstractUser

from django.urls import reverse
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.utils.text import slugify


class UserProfile(AbstractUser):
    real_name = models.CharField(max_length=32, verbose_name="真实姓名")
    gender = models.CharField(max_length=6, choices=(('male', '男'), ('female', '女')), default='female',
                              verbose_name='性别')
    phone_num = models.CharField(max_length=20, blank=True, verbose_name='电话号码')


User = get_user_model()

"""
台网相关
"""


class Network(models.Model):
    """
    台网信息
    """
    TYPE_CHOICE = (
        (0, '实验台网'),
        (1, '固定台网'),
        (2, '其它台网')
    )
    code = models.CharField(max_length=10, unique=True, verbose_name="台网代码")
    slug = models.SlugField(editable=False)
    name_zh = models.CharField(max_length=64, null=True, blank=True, verbose_name="台网名称(中文)")
    name_en = models.CharField(max_length=64, null=True, blank=True, verbose_name="台网名称(英文)")
    start_date = models.DateField("开始时间", null=True, blank=True)
    end_date = models.DateField("结束时间", null=True, blank=True)
    type = models.PositiveSmallIntegerField(choices=TYPE_CHOICE, default=0, verbose_name="台网分类")
    describe = models.TextField(blank=True, null=True, verbose_name="台网描述")

    c_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    m_time = models.DateTimeField(auto_now=True, verbose_name="更新日期")

    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')

    class Meta:
        verbose_name = "台网信息"
        verbose_name_plural = "台网信息"

    def __str__(self):
        return self.code

    def save(self, *args, **kwargs):
        self.slug = slugify(self.code)
        self.code = self.code.upper()

        super(Network, self).save(*args, **kwargs)

    # def get_absolute_url(self):
    #     return reverse("seisnet:network", kwargs={"code": self.code})


def set_default_network():
    return Network.objects.get(code="XX").pk


class Station(models.Model):
    """
    台站信息
    """
    STATION_STATUS = (
        (0, '运行'),
        (1, '测试'),
        (2, '故障'),
        (3, '暂停'),
        (4, '下线')
    )
    network = models.ForeignKey('Network', default=set_default_network, on_delete=models.SET_DEFAULT,
                                verbose_name="所属台网")
    code = models.CharField(max_length=10, verbose_name="台站代码")
    slug = models.SlugField(editable=False)
    name_zh = models.CharField(max_length=64, null=True, blank=True, verbose_name="台站名称(中文)")
    name_en = models.CharField(max_length=64, null=True, blank=True, verbose_name="台站名称(英文)")
    longitude = models.FloatField(default=0.0, verbose_name="台站经度")
    latitude = models.FloatField(default=0.0, verbose_name="台站纬度")
    altitude = models.FloatField(default=0.0, verbose_name="台站高程")
    status = models.PositiveSmallIntegerField(choices=STATION_STATUS, default=0, verbose_name="台站状态")
    location = models.TextField(null=True, blank=True, verbose_name="位置描述")
    describe = models.TextField(null=True, blank=True, verbose_name="台站描述")

    create_date = models.DateField(default=datetime.date(2011, 1, 1), verbose_name="台站建成日期")
    modify_date = models.DateField(default=datetime.date(2011, 1, 1), verbose_name="台站最近修改日期")
    end_date = models.DateField(null=True, blank=True, verbose_name='台站结束观测日期')

    c_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    m_time = models.DateTimeField(auto_now=True, verbose_name="更新日期")

    is_deleted = models.BooleanField(default=False, verbose_name='是否删除')

    class Meta:
        verbose_name = "台站信息"
        verbose_name_plural = "台站信息"
        unique_together = ('network', 'code')

    def __str__(self):
        return "{network}/{code}".format(
            network=self.network,
            code=self.code,
        )

    def save(self, *args, **kwargs):
        self.slug = slugify(self.code)
        self.code = self.code.upper()
        super(Station, self).save(*args, **kwargs)

    # def get_absolute_url(self):
    #     return reverse("seisnet:station_detail", kwargs={"network_code": self.network, "code": self.code})


"""
设备信息
"""


class EquipmentClazz(models.Model):
    parent = models.ForeignKey('self', blank=True, null=True, limit_choices_to={'parent__isnull': True},
                               on_delete=models.SET_NULL, verbose_name='父分类')
    name = models.CharField(max_length=100, verbose_name='分类名称')

    class Meta:
        verbose_name = '设备分类'
        verbose_name_plural = '设备分类'

    def __str__(self):
        return self.name


class EquipmentModel(models.Model):
    """
    设备公共信息
    抽象类
    """
    brand = models.CharField(max_length=200, verbose_name='品牌')
    name = models.CharField(max_length=200, verbose_name='型号')
    feature = models.CharField(max_length=200, null=True, blank=True, verbose_name='特征字段')
    total_quantity = models.PositiveSmallIntegerField(default=0, verbose_name='总数')
    online_quantity = models.PositiveSmallIntegerField(default=0, verbose_name='在用')
    instock_quantity = models.PositiveSmallIntegerField(default=0, verbose_name='库存数')
    damage_quantity = models.PositiveSmallIntegerField(default=0, verbose_name='损坏数')
    lend_quantity = models.PositiveSmallIntegerField(default=0, verbose_name='借出数')
    remark = models.TextField(null=True, blank=True, verbose_name='备注')
    clazz = models.ForeignKey(EquipmentClazz, on_delete=models.SET_DEFAULT, limit_choices_to={'parent__isnull': False},
                              default=1, verbose_name='设备分类')
    is_unique_sign = models.BooleanField(default=False, verbose_name="设备是否有唯一标示")

    class Meta:
        # abstract = True
        verbose_name = '设备'
        verbose_name_plural = '设备'
        unique_together = ('brand', 'name', 'feature',)

    def __str__(self):
        return self.name


class EquipmentEntity(models.Model):
    """
    有唯一标示的设备实体
    """
    STATUS_TYPE = (
        ('STOCK', '库存'),
        ('ONLINE', '在线'),
        ('UNDER_DETECTION', '待检测'),
        ('BREAKDOWN', '故障'),
        ('REPAIR', '返修'),
    )

    sn = models.CharField(max_length=20, verbose_name="设备序列号")
    model = models.ForeignKey(EquipmentModel, limit_choices_to={'is_unique_sign': True}, on_delete=models.DO_NOTHING)
    status = models.CharField(choices=STATUS_TYPE, max_length=20, default='STOCK')
    # belong_list = models.ForeignKey('EquipmentList', on_delete=models.SET_NULL, null=True, blank=True,
    #                                 related_name="seismic_equipment_entities")

# class PowerSupplyModel(EquipmentModel):
#     """
#     供电设备
#     """
#     STORAGE_BATTERY = 'SB'
#     SOLAR_POWER = 'SP'
#     SMART_CHARGER = 'SC'
#     ACDC_POWER = 'AD'
#     OTHER = 'OT'
#
#     POWER_SUPPLY_TYPE = (
#         (STORAGE_BATTERY, '电瓶'),
#         (SOLAR_POWER, '太阳能'),
#         (SMART_CHARGER, '智能充电器'),
#         (ACDC_POWER, '开关电源'),
#         (OTHER, '其它')
#     )
#
#     type = models.CharField(choices=POWER_SUPPLY_TYPE, max_length=6, verbose_name='分类')
#
#     class Meta:
#         verbose_name = '供电设备'
#         verbose_name_plural = '供电设备'
#
#     def __str__(self):
#         return '[{type}] {brand}/{name}'.format(type=self.get_type_display(), brand=self.brand, name=self.name)
#
#
# class NetworkDeviceModel(EquipmentModel):
#     """
#     网络设备
#     """
#     ROUTER = 'RT'
#     INTERCHANGER = 'IC'
#     PHOTOELECTRIC_CONVERTER = 'PEC'
#     OTHER = 'OT'
#
#     NETWORK_DEVICE_TYPE = (
#         (ROUTER, '路由器'),
#         (INTERCHANGER, '交换机'),
#         (PHOTOELECTRIC_CONVERTER, '光电转换器'),
#         (OTHER, '其它'),
#     )
#
#     type = models.CharField(choices=NETWORK_DEVICE_TYPE, max_length=6, verbose_name='分类')
#
#     class Meta:
#         verbose_name = '通讯设备'
#         verbose_name_plural = '通讯设备'
#
#     def __str__(self):
#         return '[{type}] {brand}/{name}'.format(type=self.get_type_display(), brand=self.brand, name=self.name)
#
#
# class AccessoriesModel(EquipmentModel):
#     """
#     设备配件
#     """
#     GPS_ANTENNA = 'GPS'
#     GPS_LINE = 'GL'
#     SENSOR_LINE = 'SL'
#     DATA_LINE = 'DL'
#     OTHER = 'OT'
#
#     ACCESSORIES_TYPE = (
#         (GPS_ANTENNA, 'GPS天线'),
#         (GPS_LINE, 'GPS连接线'),
#         (DATA_LINE, '数据传输线'),
#         (SENSOR_LINE, '摆线'),
#         (OTHER, '其它'),
#     )
#
#     type = models.CharField(choices=ACCESSORIES_TYPE, max_length=6, verbose_name='分类')
#
#     class Meta:
#         verbose_name = '重要配件'
#         verbose_name_plural = '重要配件'
#
#     def __str__(self):
#         return '[{type}] {brand}/{name}'.format(type=self.get_type_display(), brand=self.brand, name=self.name)


# class SeismicEquipmentModel(EquipmentModel):
#     """
#     测震设备
#     """
#     SENSOR = 'SS'
#     DATALOGGING = 'DL'
#     ALL_IN_ONE = 'AIO'
#     OTHER = 'OT'
#
#     SEISMIC_EQUIPMENT_TYPE = (
#         (SENSOR, '测震仪'),
#         (DATALOGGING, '数据采集器'),
#         (ALL_IN_ONE, '一体机'),
#         (OTHER, '其它'),
#     )
#
#     type = models.CharField(choices=SEISMIC_EQUIPMENT_TYPE, max_length=6, verbose_name='分类')
#
#     # accessories = models.ManyToManyField('AccessoriesModel', verbose_name='重要配件')
#
#     class Meta:
#         verbose_name = '测震仪器型号'
#         verbose_name_plural = '测震仪器型号'
#
#     def __str__(self):
#         feature = "/{}".format(self.feature)
#         if not self.feature:
#             feature = ""
#
#         return '[{type}] {brand} {name}{feature}'.format(type=self.get_type_display(), brand=self.brand,
#                                                          name=self.name, feature=feature)


# class SeismicEquipmentEntity(models.Model):
#     STATUS_TYPE = (
#         ('STOCK', '库存'),
#         ('ONLINE', '在线'),
#         ('UNDER_DETECTION', '待检测'),
#         ('BREAKDOWN', '故障'),
#         ('REPAIR', '返修'),
#     )
#
#     sn = models.CharField(max_length=20)
#     model = models.ForeignKey(SeismicEquipmentModel, on_delete=models.DO_NOTHING)
#     status = models.CharField(choices=STATUS_TYPE, max_length=20, default='STOCK')
#     belong_list = models.ForeignKey('EquipmentList', on_delete=models.SET_NULL, null=True, blank=True,
#                                     related_name="seismic_equipment_entities")
#
#     class Meta:
#         verbose_name = '测震仪器实体'
#         verbose_name_plural = '测震仪器实体'
#         unique_together = ('sn', 'model')
#
#     def __str__(self):
#         return '{model} ({sn})'.format(model=self.model, sn=self.sn)


# class EquipmentList(models.Model):
#     """
#     台站设备列表(最终)
#     """
#     station = models.OneToOneField('seisnet.Station', on_delete=models.CASCADE, verbose_name='所属台站')
#
#     class Meta:
#         verbose_name = '台站设备列表'
#         verbose_name_plural = '台站设备列表'
#
#     def __str__(self):
#         return "{station}'s equipment list".format(station=self.station)
#
#     def get_absolute_url(self):
#         return reverse('seisnet:station_detail',
#                        kwargs={'network_code': self.station.network.code, 'code': self.station.code})
#
#
# class ItemManager(models.Manager):
#     def powersupply(self):
#         ct = ContentType.objects.get_for_model(PowerSupplyModel)
#         return self.filter(content_type=ct)
#
#     def networkdevice(self):
#         ct = ContentType.objects.get_for_model(NetworkDeviceModel)
#         return self.filter(content_type=ct)
#
#     def accessories(self):
#         ct = ContentType.objects.get_for_model(AccessoriesModel)
#         return self.filter(content_type=ct)
#
#
# class EquipmentItem(models.Model):
#     """
#     所属台站设备名称及个数
#     """
#     belong_list = models.ForeignKey('EquipmentList', on_delete=models.CASCADE, null=True, blank=True,
#                                     related_name="equipment_items")
#     content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE,
#                                      limit_choices_to={
#                                          'model__in': ('powersupplymodel', 'networkdevicemodel', 'accessoriesmodel')})
#     object_id = models.PositiveIntegerField()
#     equipment = GenericForeignKey('content_type', 'object_id')
#     quantity = models.PositiveIntegerField(default=1, verbose_name='数量')
#
#     objects = ItemManager()
#
#     class Meta:
#         verbose_name = '台站设备条目'
#         verbose_name_plural = '台站设备条目'
#
#
# class AccessoriesItem(models.Model):
#     """
#     重要配件条目列表
#     """
#     belong_seismodel = models.ForeignKey('SeismicEquipmentModel', on_delete=models.CASCADE, verbose_name='测震仪器配件')
#     accessories = models.ForeignKey('AccessoriesModel', on_delete=models.CASCADE, verbose_name='配件列表')
#     quantity = models.PositiveIntegerField(default=0, verbose_name='数量')
